﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using DataBaseAccessLib;
using System.Data;
using System.ComponentModel;
using MemCached;

namespace BusinessModel
{
    public class EntityOprHelper
    {
        CMemCached mc = new CMemCached();

        /// <summary>
        /// 获取所有的材料清单数据
        /// </summary>
        /// <param name="pageSize">页面记录数</param>
        /// <param name="currentPage">当前页</param>
        /// <param name="pager">分页控件</param>
        /// <param name="sortExpression">排序字段</param>
        /// <param name="sortDirection">排序方式</param>
        /// <param name="condition">查询条件</param>
        /// <returns></returns>
        public List<T> GetEntityList<T>(int pageSize, int currentPage, Wuqi.Webdiyer.AspNetPager pager, string sortExpression, string sortDirection, string condition)where T:new()
        {
            int totalPage = 0, totalRow = 0;//总页数，总记录数
            SQLScript sqlScript = new SQLScript();
            DataTable table = null;
            List<T> entityList = new List<T>(); 
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));
            try
            {
                if (mc.KeyExist(classAttribute.TableName + currentPage))
                {
                    //获取
                    table = (DataTable)mc.GetObject(classAttribute.TableName + currentPage);
                    totalRow = (int)mc.GetObject(classAttribute.TableName + "TotalRow");
                }
                else
                {
                    IDBAccess DB = DBFactory.GetDBAccess(OConfig.SysDBType, OConfig.DBConnection);
                    int startIndex, endIndex;
                    string strCol = " a.*";
                    OConfig.GetStartRowNum(" " + classAttribute.TableName + " a ", condition, currentPage, pageSize, out startIndex, out endIndex, out totalPage, out totalRow);
                    string sqlCommand = sqlScript.QueryByDividePage(" " + classAttribute.TableName + " a ", condition, strCol, sortExpression + " " + sortDirection, startIndex, endIndex);
                    table = DB.ExecuteDataTable(sqlCommand, CommandType.Text, null);

                    //存储
                    mc.SetObject(classAttribute.TableName + currentPage, table);
                    mc.SetObject(classAttribute.TableName + "TotalRow", totalRow);
                }
                if (table.Rows.Count > 0)
                {

                    for (int i = 0; i < table.Rows.Count; i++)
                    {
                        T entity = new T();
                        foreach (var p in properties)
                        {
                            if (table.Columns.Contains(p.Name) && table.Rows[i][p.Name] != null&&table.Rows[i][p.Name].ToString()!="")
                            {
                                var value = this.ChangeType(table.Rows[i][p.Name], p.PropertyType);
                                p.SetValue(entity, value, null);
                            }

                        }
                        entityList.Add(entity);
                    }
                }
                pager.RecordCount = totalRow;
                if (currentPage > pager.PageCount)
                {
                    currentPage = pager.PageCount;
                }
                if (currentPage == 0)
                {
                    currentPage = 1;
                }
                pager.CurrentPageIndex = currentPage;
            }
            catch (Exception exp)
            {
                table = null;
            }
            finally
            {
                pager.CustomInfoHTML = "共<font color=red>" + pager.RecordCount + "</font>条数据 当前<font color=red>" + pager.CurrentPageIndex + "/" + pager.PageCount + "</font>页";
            }
            //mc.ClosePool();
            return entityList;

        }

        /// <summary>
        /// 得到一个对象实体
        /// </summary>
        public T GetEntity<T>(string key) where T : new()
        {
            T t=new T();
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));

            // return t;
            StringBuilder strSql = new StringBuilder();
            DBType dbType = OConfig.SysDBType;
            IDBAccess DB = DBFactory.GetDBAccess(dbType, OConfig.DBConnection);
            strSql.Append("select  ");
            strSql.Append(" * ");
            strSql.Append(" from ");
            strSql.Append(classAttribute.TableName);
            strSql.Append(" where ");
            strSql.Append(classAttribute.KeyName + "='" + key + "' ");

            DataSet ds = DB.ExecuteDataSet(strSql.ToString(), CommandType.Text, null);
            if (ds.Tables[0].Rows.Count > 0)
            {
                foreach (var p in properties)
                {
                    if (ds.Tables[0].Columns.Contains(p.Name) && ds.Tables[0].Rows[0][p.Name] != null)
                    {
                        var value = this.ChangeType(ds.Tables[0].Rows[0][p.Name], p.PropertyType);
                        p.SetValue(t, value, null);
                    }

                }
                
            }
            else
            {
                return default(T);
            }
            return t;

        }

        /// <summary>
        /// 删除记录
        /// </summary>
        public bool DelEntity<T>(T t)
        {
            Type type = t.GetType();
            PropertyInfo[] properties = type.GetProperties();
            var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));

            StringBuilder strSql = new StringBuilder();
            DBType dbType = OConfig.SysDBType;
            IDBAccess DB = DBFactory.GetDBAccess(dbType, OConfig.DBConnection);
            strSql.Append("delete from " + classAttribute.TableName);
            strSql.Append(" where " + classAttribute.KeyName + "='" + type.GetProperty(classAttribute.KeyName).GetValue(t, null) + "' ");
            int isSuccess = DB.ExecuteNonQuery(strSql.ToString(), CommandType.Text, null);
            if (isSuccess > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool ExecuteNonQuery(string sql)
        {
            DBType dbType = OConfig.SysDBType;
            IDBAccess DB = DBFactory.GetDBAccess(dbType, OConfig.DBConnection);
            int isSuccess = DB.ExecuteNonQuery(sql, CommandType.Text, null);
            if (isSuccess > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 添加一条记录
        /// </summary>
        public bool AddEntity<T>(T t)
        {
            try
            {
                Type type = t.GetType();
                PropertyInfo[] properties = type.GetProperties();
                var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));

                StringBuilder strSql = new StringBuilder();
                StringBuilder strSql1 = new StringBuilder();
                StringBuilder strSql2 = new StringBuilder();
                DBType dbType = OConfig.SysDBType;
                IDBAccess DB = DBFactory.GetDBAccess(dbType, OConfig.DBConnection);

                foreach (var p in properties)
                {
                    if (p.GetValue(t, null) != null)
                    {
                        strSql1.Append(p.Name + ",");
                        strSql2.Append("'" + p.GetValue(t, null) + "',");
                    }
                }

                strSql.Append("insert into " + classAttribute.TableName + "(");
                strSql.Append(strSql1.ToString().Remove(strSql1.Length - 1));
                strSql.Append(")");
                strSql.Append(" values (");
                strSql.Append(strSql2.ToString().Remove(strSql2.Length - 1));
                strSql.Append(")");
                int isSuccess = DB.ExecuteNonQuery(strSql.ToString(), CommandType.Text, null);
                if (isSuccess > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                return false;
            }

        }

        /// <summary>
        /// 编辑一条记录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool EditEntity<T>(T t)
        {
            try
            {
                Type type = t.GetType();
                PropertyInfo[] properties = type.GetProperties();
                var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));

                StringBuilder strSql = new StringBuilder();
                DBType dbType = OConfig.SysDBType;
                IDBAccess DB = DBFactory.GetDBAccess(dbType, OConfig.DBConnection);
                strSql.Append("update " + classAttribute.TableName + " set ");
                foreach (var p in properties)
                {
                    if (p.GetValue(t, null) != null)
                    {
                        strSql.Append(p.Name + "='" + p.GetValue(t, null) + "',");

                    }
                }

                int n = strSql.ToString().LastIndexOf(",");
                strSql.Remove(n, 1);
                strSql.Append(" where " + classAttribute.KeyName + "='" + type.GetProperty(classAttribute.KeyName).GetValue(t, null) + "' ");
                int isSuccess = DB.ExecuteNonQuery(strSql.ToString(), CommandType.Text, null);
                if (isSuccess > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                return false;
            }

        }

        /// <summary>
        /// 得到对象实体集合
        /// </summary>
        public List<T> GetEntityList<T>(string WhereStr) where T : new()
        {
            //T o;
            // o.GetType
            List<T> entityList = new List<T>();
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));

            // return t;
            StringBuilder strSql = new StringBuilder();
            DBType dbType = OConfig.SysDBType;
            IDBAccess DB = DBFactory.GetDBAccess(dbType, OConfig.DBConnection);
            strSql.Append("select  ");
            strSql.Append(" * ");
            strSql.Append(" from ");
            strSql.Append(classAttribute.TableName);
            if (!string.IsNullOrEmpty(WhereStr))
            {
                strSql.Append(WhereStr);
            }

            DataSet ds = DB.ExecuteDataSet(strSql.ToString(), CommandType.Text, null);
            if (ds.Tables[0].Rows.Count > 0)
            {

                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    T entity = new T();
                    foreach (var p in properties)
                    {
                        if (ds.Tables[0].Columns.Contains(p.Name) && ds.Tables[0].Rows[i][p.Name] != null && ds.Tables[0].Rows[i][p.Name].ToString()!="")
                        {
                            var value = this.ChangeType(ds.Tables[0].Rows[i][p.Name], p.PropertyType);
                            p.SetValue(entity, value, null);
                        }
                     
                    }
                    entityList.Add(entity);
                }
            }
            return entityList;

        }

        //Nullable类型处理
        public  object ChangeType(object value, Type conversionType)
        {
            if (value == null)
                return null;
            if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                if (value != null)
                {
                    NullableConverter nullableConverter = new NullableConverter(conversionType);
                    conversionType = nullableConverter.UnderlyingType;
                }
                else
                {
                    return null;
                }
            }

            return Convert.ChangeType(value, conversionType);
        }

        /// <summary>
        /// 得到对象实体集合
        /// </summary>
        public List<T> GetEntityListBySql<T>(string sqlstr) where T : new()
        {
            //T o;
            // o.GetType
            List<T> entityList = new List<T>();
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));

            // return t;
            
            DBType dbType = OConfig.SysDBType;
            IDBAccess DB = DBFactory.GetDBAccess(dbType, OConfig.DBConnection);



            DataSet ds = DB.ExecuteDataSet(sqlstr, CommandType.Text, null);
            if (ds.Tables[0].Rows.Count > 0)
            {

                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    T entity = new T();
                    foreach (var p in properties)
                    {
                        if (ds.Tables[0].Columns.Contains(p.Name) && ds.Tables[0].Rows[i][p.Name] != null && ds.Tables[0].Rows[i][p.Name].ToString() != "")
                        {
                            var value = this.ChangeType(ds.Tables[0].Rows[i][p.Name], p.PropertyType);
                            p.SetValue(entity, value, null);
                        }

                    }
                    entityList.Add(entity);
                }
            }
            return entityList;

        }

        /// <summary>
        /// 获取所有的材料清单数据
        /// </summary>
        /// <param name="pageSize">页面记录数</param>
        /// <param name="currentPage">当前页</param>
        /// <param name="pager">分页控件</param>
        /// <param name="sortExpression">排序字段</param>
        /// <param name="sortDirection">排序方式</param>
        /// <param name="condition">查询条件</param>
        /// <returns></returns>
        public List<T> GetEntityListBySql<T>(string sqlstr,int pageSize, int currentPage, Wuqi.Webdiyer.AspNetPager pager,string memcachName) where T : new()
        {
            int totalPage = 0, totalRow = 0;//总页数，总记录数
            SQLScript sqlScript = new SQLScript();
            DataTable table = null;
            List<T> entityList = new List<T>();
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            var classAttribute = (CustomAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(CustomAttribute));
            try
            {
                if (mc.KeyExist(classAttribute.TableName + currentPage))
                {
                    //获取
                    table = (DataTable)mc.GetObject(memcachName + currentPage);
                    totalRow = (int)mc.GetObject(memcachName + "TotalRow");
                }
                else
                {
                    IDBAccess DB = DBFactory.GetDBAccess(OConfig.SysDBType, OConfig.DBConnection);
                    int startIndex, endIndex;
                   // string strCol = " a.*";
                    OConfig.GetStartRowNum("select count(*) from (" + sqlstr + ") tmp", currentPage, pageSize, out startIndex, out endIndex, out totalPage, out totalRow);
                    //string sqlCommand = sqlScript.QueryByDividePage(" " + classAttribute.TableName + " a ", condition, strCol, sortExpression + " " + sortDirection, startIndex, endIndex);
                    string sqlCommand;// =  "select * from (" + sqlstr + ") tmp  where rownum between " + startIndex + " and " + endIndex;
                    sqlCommand = "SELECT  * FROM (" +
                        "select tmp.*,rownum rn from(" + sqlstr + ") tmp where rownum<=" + endIndex + ")" +
                        " WHERE rn >= " + startIndex;
                    table = DB.ExecuteDataTable(sqlCommand, CommandType.Text, null);

                    //存储
                    mc.SetObject(memcachName + currentPage, table);
                    mc.SetObject(memcachName + "TotalRow", totalRow);
                }
                if (table.Rows.Count > 0)
                {

                    for (int i = 0; i < table.Rows.Count; i++)
                    {
                        T entity = new T();
                        foreach (var p in properties)
                        {
                            if (table.Columns.Contains(p.Name) && table.Rows[i][p.Name] != null && table.Rows[i][p.Name].ToString()!="")
                            {
                                var value = this.ChangeType(table.Rows[i][p.Name], p.PropertyType);
                                p.SetValue(entity, value, null);
                            }

                        }
                        entityList.Add(entity);
                    }
                }
                pager.RecordCount = totalRow;
                if (currentPage > pager.PageCount)
                {
                    currentPage = pager.PageCount;
                }
                if (currentPage == 0)
                {
                    currentPage = 1;
                }
                pager.CurrentPageIndex = currentPage;

                
            }
            catch (Exception exp)
            {
                table = null;
            }
            finally
            {
                pager.CustomInfoHTML = "共<font color=red>" + pager.RecordCount + "</font>条数据 当前<font color=red>" + pager.CurrentPageIndex + "/" + pager.PageCount + "</font>页";
            }
            //mc.ClosePool();
            return entityList;

        }

    }
}
